package com.hera.base.util.exception;

import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.Locale;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.context.MessageSource;
import org.springframework.dao.DataIntegrityViolationException;

import com.hera.base.util.DateUtil;
import com.vaadin.server.ErrorEvent;
import com.vaadin.server.ErrorHandler;
import com.vaadin.server.Page;
import com.vaadin.ui.Notification;

public class ManejadorExcepcionMensaje implements ErrorHandler {

	private static final long serialVersionUID = 1L;
	private static Logger log = Logger.getLogger(ManejadorExcepcionMensaje.class);

	private MessageSource messageSource;
	Locale locale;

	public ManejadorExcepcionMensaje(MessageSource messageSource, Locale locale) {
		this.messageSource = messageSource;
		this.locale = locale;
	}

	@Override
	public void error(ErrorEvent event) {
		if(event.getThrowable().getCause() instanceof InvocationTargetException){
			InvocationTargetException ite = (InvocationTargetException)event.getThrowable().getCause();
		if(ite==null){
			manejarExcepcion((Exception)event.getThrowable());
		}else if(ite.getTargetException().getCause()==null){
			manejarExcepcion((Exception)ite.getTargetException());
		}else{
			manejarExcepcion((Exception)ite.getTargetException().getCause());
		}
		}else{
			manejarExcepcion((Exception)event.getThrowable());
		}

	}

	private void manejarExcepcion(Exception excepcion) {
		String defaultMessage = "Mensaje no especificado";
		if (excepcion instanceof ValidationException) {
			resolverException((ValidationException) excepcion, defaultMessage);
		} else if (excepcion instanceof BusinessException) {
			resolverException((BusinessException) excepcion, defaultMessage);
		} else if (excepcion instanceof LoginException) {
			resolverException((LoginException) excepcion, defaultMessage);
		} else if (excepcion instanceof CommunicationException) {
			resolverException((CommunicationException) excepcion, defaultMessage);
		} else if (excepcion instanceof BaseException) {
			resolverException((BaseException) excepcion, defaultMessage);
		} else if(excepcion instanceof DataIntegrityViolationException){
			manejarExcepcion((Exception)excepcion.getCause());
		} else if(excepcion instanceof ConstraintViolationException){
//			ValidationException validationException=new ValidationException(Constantes.CODIGO_MENSAJE.REGISTROS_RELACIONADOS);
//			resolverException(validationException, defaultMessage);
		}else {
			resolverException(excepcion, defaultMessage);
		}
	}

	private void resolverException(BusinessException businessException, String defaultMessage) {
		if (businessException.getCodigoMensaje() == null || businessException.getCodigoMensaje().equals("")) {
			if (businessException.getException() != null) {
				resolverException(businessException.getException(), defaultMessage);
			}
		}
		String mensaje = "" + messageSource.getMessage(businessException.getCodigoMensaje(), businessException.getParametros(), defaultMessage, locale);
		mostrarNotificacion(businessException.getTitulo(), mensaje, Notification.Type.HUMANIZED_MESSAGE);

	}

	private void resolverException(ValidationException validationException, String defaultMessage) {
		String mensaje = "" + messageSource.getMessage(validationException.getCodigoMensaje(), validationException.getParametros(), defaultMessage, locale);
		
		
		mostrarNotificacion(validationException.getTitulo(), mensaje, Notification.Type.WARNING_MESSAGE);

	}

	private void resolverException(CommunicationException communicationException, String defaultMessage) {
		String mensaje = "" + messageSource.getMessage(communicationException.getCodigoMensaje(), communicationException.getParametros(), defaultMessage, locale);
		mostrarNotificacion(communicationException.getTitulo(), mensaje + ": " + communicationException.getException().getMessage(), Notification.Type.WARNING_MESSAGE);
	}

	private void resolverException(LoginException loginException, String defaultMessage) {
		String mensaje = "" + messageSource.getMessage(loginException.getCodigoMensaje(), loginException.getParametros(), defaultMessage, locale);
		mostrarNotificacion(loginException.getTitulo(), mensaje, Notification.Type.WARNING_MESSAGE);
	}
	
	
	private void mostrarNotificacion(String titulo,String mensaje, Notification.Type tipo){
		Notification notification = new Notification(titulo, mensaje, Notification.Type.WARNING_MESSAGE);
        //notification.setDelayMsec(15);
		notification.setDelayMsec(Notification.DELAY_FOREVER);
        notification.setStyleName("alert");
        notification.setCaption("");
        notification.setDescription("<div class=\"notification-title v-window-outerheader\">"+titulo+"</div><br/><div >"+mensaje+"</div><br/><br/>"
        		+"<div class=\"v-button v-widget v-has-width\" style=\"width: 100px;\"><span class=\"v-button-wrap\"><span class=\"v-button-caption\">Aceptar</span></span></div>");
        //notification.setIcon(new ThemeResource("images/close_btn_hover.png"));
        notification.setHtmlContentAllowed(true);
        notification.show(Page.getCurrent());
	}

	private void resolverException(Exception exception, String defaultMessage) {
		String tiket = DateUtil.getFecha(new Date(), "yyyyMMddHHmmss");
//		String[] parametro = { tiket };
		String mensaje = "" ;//+ 
		if (exception instanceof BaseException) {
			BaseException baseException = (BaseException) exception;
			mensaje = "" + messageSource.getMessage(baseException.getCodigoMensaje(), baseException.getParametros(), locale);
		} else {
			mensaje = "" + exception.getMessage();
		}
		mostrarNotificacion("ERROR inesperado", mensaje, Notification.Type.ERROR_MESSAGE);
		log.info(StringUtils.leftPad("*", 100, "*"));
		log.info(StringUtils.leftPad("*", 35, "*") + " INICIO TIKET: " + tiket + " " + StringUtils.leftPad("*", 35, "*"));
		log.info(StringUtils.leftPad("*", 100, "*"));
		log.info(exception.getMessage(), exception);
		log.info(StringUtils.leftPad("*", 100, "*"));
		log.info(StringUtils.leftPad("*", 35, "*") + "  FIN TIKET:  " + tiket + "  " + StringUtils.leftPad("*", 35, "*"));
		log.info(StringUtils.leftPad("*", 100, "*"));

	}

}
